﻿#region File and License Information
/*
<File>
	<Copyright>Copyright © 2007, Daniel Vaughan. All rights reserved.</Copyright>
	<License see="prj:///Documentation/License.txt"/>
	<Owner Name="Daniel Vaughan" Email="dbvaughan@gmail.com"/>
	<CreationDate>2009-04-25 14:43:57Z</CreationDate>
	<LastSubmissionDate>$Date: $</LastSubmissionDate>
	<Version>$Revision: $</Version>
</File>
*/
#endregion

using System;

using DanielVaughan.Resources;

namespace DanielVaughan.Services.Implementation
{
	public enum MessageImage
	{
		None,
		Asterisk,
		Error,
		Exclamation,
		Hand,
		Information,
		Question,
		Stop,
		Warning
	}

	public enum MessageButton
	{
		OK = 0,
		OKCancel = 1,
		YesNo = 4,
		YesNoCancel = 3
	}

	public enum MessageResult
	{
		Cancel = 2,
		No = 7,
		None = 0,
		OK = 1,
		Yes = 6
	}

	/// <summary>
	/// Base implementation of <see cref="IMessageService"/>.
	/// </summary>
	public abstract class MessageServiceBase : IMessageService
	{
		/*TODO: implement a means to modify the user MessageImportance threshold value. This be done by subscribing to a composite property changed event. */
		public static MessageImportance MinumumImportance { get; protected set; }

		static MessageServiceBase()
		{
			MinumumImportance = MessageImportance.Low;
		}

		/// <summary>
		/// Shows a custom dialogue. Override this message in test mocks.
		/// This is the only place where a MessageBox is shown.
		/// </summary>
		/// <param name="message">The message text to display.</param>
		/// <param name="details">Can be <code>null</code>. 
		/// A detailed message that is display in a hidden area of the dialog, 
		/// and revealed on user request.</param>
		/// <param name="caption">The caption to display at the top of the dialog.</param>
		/// <param name="messageButton">The message box button enum value, 
		/// which determines what buttons are shown.</param>
		/// <param name="messageImage">The message box image, 
		/// which determines what icon is used.</param>
		/// <param name="importanceThreshold">The minimum filter level 
		/// that a user must have in order to receive the message.</param>
		/// <returns>The result of showing the message box.</returns>
		public abstract MessageResult ShowCustomDialog(string message, string caption,
														  MessageButton messageButton, MessageImage messageImage,
														  MessageImportance? importanceThreshold, string details);

		#region Messages
		public void ShowMessage(string message, MessageImportance importanceThreshold)
		{
			ShowMessage(message, null, importanceThreshold);
		}

		public void ShowMessage(string message, string caption, MessageImportance importanceThreshold)
		{
			ShowMessage(message, caption, importanceThreshold, null);
		}

		public void ShowMessage(string message, string caption, MessageImportance importanceThreshold, string details)
		{
			ShowCustomDialog(message, caption ?? StringResources.Services_MessageService_MessageCaption, 
				MessageButton.OK, MessageImage.Information, importanceThreshold, details);
		}
		#endregion

		#region Warnings
		public void ShowWarning(string message)
		{
			ShowWarning(message, null);
		}

		public void ShowWarning(string message, string details)
		{
			ShowWarning(message, details, null);
		}

		public void ShowWarning(string message, string caption, string details)
		{
			ShowCustomDialog(message, caption ?? StringResources.Services_MessageService_WarningCaption,
				MessageButton.OK, MessageImage.Warning, null, details);
		}
		#endregion

		#region Errors
		public void ShowError(string message)
		{
			ShowError(message, null);
		}

		public void ShowError(string message, string caption)
		{
			ShowError(message, caption, null);
		}

		public void ShowError(string message, string caption, string details)
		{
			ShowCustomDialog(message, caption ?? StringResources.Services_MessageService_ErrorCaption, 
				MessageButton.OK, MessageImage.Error, null, details);
		}
		#endregion

		#region Questions
		public bool AskYesNoQuestion(string question)
		{
			return AskYesNoQuestion(question, null);
		}

		public bool AskYesNoQuestion(string question, string caption)
		{
			var messageBoxResult = ShowCustomDialog(question, caption ?? StringResources.Services_MessageService_QuestionCaption, 
				MessageButton.YesNo, MessageImage.Question, null, null);
			return messageBoxResult == MessageResult.Yes 
				|| messageBoxResult == MessageResult.OK;
		}

		public bool AskOkCancelQuestion(string question)
		{
			return AskYesNoQuestion(question, null);
		}

		public bool AskOkCancelQuestion(string question, string caption)
		{
			var messageBoxResult = ShowCustomDialog(question, caption ?? StringResources.Services_MessageService_QuestionCaption, 
				MessageButton.OKCancel, MessageImage.Question, null, null);
			return messageBoxResult == MessageResult.OK 
				|| messageBoxResult == MessageResult.Yes;
		}

		public YesNoCancelQuestionResult AskYesNoCancelQuestion(string question)
		{
			return AskYesNoCancelQuestion(question, null);
		}

		public YesNoCancelQuestionResult AskYesNoCancelQuestion(string question, string caption)
		{
			var dialogResult = ShowCustomDialog(question, caption ?? StringResources.Services_MessageService_QuestionCaption, 
				MessageButton.YesNoCancel, MessageImage.Question, null, null);

			switch (dialogResult)
			{
				case MessageResult.Yes:
					return YesNoCancelQuestionResult.Yes;
				case MessageResult.No:
					return YesNoCancelQuestionResult.No;
				case MessageResult.Cancel:
					return YesNoCancelQuestionResult.Cancel;
				default:
					/* Should never get here. */
					throw new InvalidOperationException("Invalid dialog MessageBoxResult."); /* TODO: Make localizable resource. */
			}
		}

		#endregion
	}
}
